﻿using System;
using System.IO;
using System.Web;
using System.Linq;
using System.Text;
using System.Collections.Generic;

namespace CSBackup_Web.Sources.Override
{
    public class ProjectInfo
    {
        private string prjName = string.Empty;
        private string prjLocation = string.Empty;
        private string resourcePath = string.Empty;
        private string bkpPrjFile = string.Empty;
        private string fullBkpPath = string.Empty;
        private string incBkpPath = string.Empty;
        private string diffBkpPath = string.Empty;
        private string diffIncBkpPath = string.Empty;
        private string recoveryPath = string.Empty;
        private int curSelTabFrm = 0;
        private int curSelTabFrmOfBkp = 0;
        private int curSelTabRcvrList = 0;
        private int autoCycle = 0;
        private int autoHour = 0;
        private int autoMin = 0;
        private int bkpProgress = 0;
        private bool isAutoBkpOnce = false;
        private bool isInclude = false;
        private bool isNew = true;

        private BackupInfo currentBackup = new BackupInfo();
        private BackupInfo selectedBackup = new BackupInfo();

        private List<BackupInfo> fullBkpList = new List<BackupInfo>();
        private List<BackupInfo> incBkpList = new List<BackupInfo>();
        private List<BackupInfo> diffBkpList = new List<BackupInfo>();
        private List<BackupInfo> diffIncBkpList = new List<BackupInfo>();
        private List<FileDetail> selectedFileList = new List<FileDetail>();
        private List<FileDetail> selectedDirList = new List<FileDetail>();
        private List<string> selectedBkpList = new List<string>();
        private List<bool> fileListValue = new List<bool>();

        public List<bool> FileListValue
        {
            set { fileListValue = value; }
            get { return fileListValue; }
        }

        public string PrjName
        {
            get { return prjName; }
            set { prjName = value; }
        }

	/// <summary>
	/// While set PrjLocation, set all directory related to the project
	/// </summary>
        public string PrjLocation
        {
            get { return prjLocation; }
            set
            {
                prjLocation = value;
                ResourcePath = Path.Combine(value, "Resource");
                FullBkpPath = Path.Combine(value, "Full");
                IncBkpPath = Path.Combine(value, "Inc");
                DiffBkpPath = Path.Combine(value, "Dif");
                DiffIncBkpPath = Path.Combine(value, "DifInc");
                RecoveryPath = Path.Combine(value, "Recovery");
            }
        }

        public string BkpPrjFile
        {
            get { return bkpPrjFile; }
            set { bkpPrjFile = value; }
        }

        public string ResourcePath
        {
            get { return resourcePath; }
            set { resourcePath = value; }
        }

        public string FullBkpPath
        {
            get { return fullBkpPath; }
            set { fullBkpPath = value; }
        }

        public string IncBkpPath
        {
            get { return incBkpPath; }
            set { incBkpPath = value; }
        }

        public string DiffBkpPath
        {
            get { return diffBkpPath; }
            set { diffBkpPath = value; }
        }

        public string DiffIncBkpPath
        {
            get { return diffIncBkpPath; }
            set { diffIncBkpPath = value; }
        }
        public string RecoveryPath
        {
            set { recoveryPath = value; }
            get { return recoveryPath; }
        }

        public int CurSelTabFrm
        {
            get { return curSelTabFrm; }
            set { curSelTabFrm = value; }
        }

        public int CurSelTabFrmOfBkp
        {
            get { return curSelTabFrmOfBkp; }
            set { curSelTabFrmOfBkp = value; }
        }

        public int CurSelTabRcvrList
        {
            get { return curSelTabRcvrList; }
            set { curSelTabRcvrList = value; }
        }

        public int AutoCycle
        {
            get { return autoCycle; }
            set { autoCycle = value; }
        }

        public int AutoHour
        {
            get { return autoHour; }
            set { autoHour = value; }
        }

        public int AutoMin
        {
            get { return autoMin; }
            set { autoMin = value; }
        }

        public int BackupProgress
        {
            get { return bkpProgress; }
            set { bkpProgress = value; }
        }

        public bool IsAutoBackupOnce
        {
            get { return isAutoBkpOnce; }
            set { isAutoBkpOnce = value; }
        }

        public bool IsInclude
        {
            get { return isInclude; }
            set { isInclude = value; }
        }

        public bool IsNew
        {
            get
            {
                return isNew;
            }
            set
            {
                isNew = value;
            }
        }

        public BackupInfo CurrentBackup
        {
            get
            {
                if (null == currentBackup)
                    currentBackup = new BackupInfo();
                return currentBackup;
            }
            set
            {
                currentBackup = value;
            }
        }

        /// <summary>
        /// 可能为null
        /// </summary>
        public BackupInfo SelectedBackup
        {
            get { return selectedBackup; }
            set { selectedBackup = value; }
        }

        public List<BackupInfo> FullBackupList
        {
            get
            {
                if (null == fullBkpList)
                    fullBkpList = new List<BackupInfo>();
                return fullBkpList;
            }
        }

        public List<BackupInfo> IncBackupList
        {
            get
            {
                if (null == incBkpList)
                    incBkpList = new List<BackupInfo>();
                return incBkpList;
            }
        }

        public List<BackupInfo> DiffBackupList
        {
            get
            {
                if (null == diffBkpList)
                    diffBkpList = new List<BackupInfo>();
                return diffBkpList;
            }
        }

        public List<BackupInfo> DiffIncBackupList
        {
            get
            {
                if (null == diffIncBkpList)
                    diffIncBkpList = new List<BackupInfo>();
                return diffIncBkpList;
            }
        }

        public List<FileDetail> SelectedFileList
        {
            get
            {
                if (null == selectedFileList)
                    selectedFileList = new List<FileDetail>();
                return selectedFileList;
            }
        }

        public List<FileDetail> SelectedDirList
        {
            get
            {
                if (null == selectedDirList)
                    selectedDirList = new List<FileDetail>();
                return selectedDirList;
            }
        }

        public List<string> SelectedBackupList
        {
            get
            {
                if (null == selectedBkpList)
                    selectedBkpList = new List<string>();
                return selectedBkpList;
            }
        }

        public void Clear()
        {
            prjName = string.Empty;
            prjLocation = string.Empty;
            bkpPrjFile = string.Empty;
            fullBkpPath = string.Empty;
            incBkpPath = string.Empty;
            diffBkpPath = string.Empty;
            diffIncBkpPath = string.Empty;
            //curSelTabFrm = 0;
            //curSelTabFrmOfBkp = 0;
            //curSelTabRcvrList = 0;
            autoCycle = 0;
            autoHour = 0;
            autoMin = 0;
            bkpProgress = 0;
            isAutoBkpOnce = false;
            isInclude = false;
            isNew = false;

            currentBackup.Init();
            selectedBackup = null;

            fullBkpList.Clear();
            incBkpList.Clear();
            diffBkpList.Clear();
            diffIncBkpList.Clear();

            selectedFileList.Clear();
            selectedDirList.Clear();

            return;
        }

        public BackupInfo GetLatestFullBackup()
        {
            BackupInfo full = null;
            foreach (BackupInfo bkp in fullBkpList)
            {
                if ((null == full)
                    || (-1 == String.Compare(full.BkpTime, bkp.BkpTime)))
                    full = bkp;
            }

            return full;
        }

        public BackupInfo GetLatestIncBackup()
        {
            BackupInfo inc = null;
            foreach (BackupInfo bkp in incBkpList)
            {
                if ((null == inc)
                    || (-1 == String.Compare(inc.BkpTime, bkp.BkpTime)))
                    inc = bkp;
            }

            return inc;
        }

        public BackupInfo GetLatestFullOrIncBackup()
        {
            BackupInfo full = GetLatestFullBackup();
            BackupInfo inc = GetLatestIncBackup();

            if (null == full)
                return inc;
            else if (null == inc)
                return full;
            else if (-1 == String.Compare(full.BkpTime, inc.BkpTime))
                return inc;
            else
                return full;
        }

        public static BackupInfo FindBackupInList(string name, List<BackupInfo> list)
        {
            if ((null == name) || (null == list))
                return null;

            foreach (BackupInfo bkp in list)
            {
                if (name == bkp.BkpName)
                    return bkp;
            }

            return null;
        }

        /// <summary>
        /// 根据备份依赖关系填充列表
        /// </summary>
        /// <param name="dependedList">待填充的依赖列表</param>
        /// <returns>0 - 成功 ; 1 - 出错 ; 2 - 参数错误</returns>
        private int FillDependedList(List<BackupInfo> dependedList)
        {
            if (null == dependedList)
                return 2;

            string dpndBkpName = string.Empty;
            BackupInfo bkpDepended = null;

            dpndBkpName = dependedList.First().BkpDepended;
            if (string.Empty == dpndBkpName)
                return 0;

            bkpDepended = FindBackupInList(dpndBkpName, fullBkpList);
            if (null == bkpDepended)
                bkpDepended = FindBackupInList(dpndBkpName, incBkpList);
            if (null == bkpDepended)
                bkpDepended = FindBackupInList(dpndBkpName, diffBkpList);
            if (null == bkpDepended)
                bkpDepended = FindBackupInList(dpndBkpName, diffIncBkpList);

            if (null == bkpDepended)
                return 1;

            dependedList.Insert(0, bkpDepended);

            //recursively fill
            return FillDependedList(dependedList);
        }

        public int FillSelfBackupHistoryList(List<BackupInfo> historyList)
        {
            if (null == historyList)
                return 2;  //参数错误

            int ret = 0;

            historyList.Insert(0, currentBackup);
            if (0 == (ret = FillDependedList(historyList)))
            {
                //移除自身
                historyList.RemoveAt(historyList.Count - 1);
                return 0;
            }

            return ret;
        }

        public int FillBackupHistoryList(BackupInfo bkp, List<BackupInfo> historyList)
        {
            if (null == bkp)
                return 0;

            if (null == historyList)
                return 2;

            int ret = 0;

            historyList.Insert(0, bkp);
            if (0 == (ret = FillDependedList(historyList)))
            {
                historyList.RemoveAt(historyList.Count - 1);
                return 0;
            }

            return ret;
        }

        /// <summary>
        /// Save the prjoect's configuration file
        /// </summary>
        /// <returns>
        /// 1 - Invalide parameter
        /// 0 - Success
        /// </returns>
        public int SaveProject()
        {
            bkpPrjFile = Path.Combine(PrjLocation, PrjName + ".bakprj");
            return ToolConfigFile.SaveConfigFile(BkpPrjFile, PrjName,
                FullBkpPath, IncBkpPath, DiffBkpPath, DiffIncBkpPath,
                AutoCycle, AutoHour, AutoMin, IsAutoBackupOnce,
                CurrentBackup.FileList);
        }
    }
}
